home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / ARGONET / PD / GRAPHICS / GIF2RPC.SPK / source / 16bpp_66bit / c / sierra2 < prev    next >
Text File  |  1995-10-16  |  4KB  |  114 lines

  1. /* sierra2.c
  2.  * AUTHOR:      Cy Booker, cy@cheepnis.demon.co.uk
  3.  * LICENSE:     FreeWare, Copyright (c) 1995 Cy Booker
  4.  *
  5.  * filter:              *  4  3
  6.  *                1  2  3  2  1         (1/16)
  7.  */
  8.  
  9. #include "internal.h"
  10.  
  11. #include <assert.h>
  12. #include <string.h>             /* memset() */
  13. #include <stdlib.h>             /* calloc() */
  14.  
  15. #include "OS:hourglass.h"
  16. #include "OS:macros.h"
  17.  
  18.  
  19.  
  20. /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  21.  */
  22.  
  23. extern bool process_gif_16bpp_sierra2_66bit(
  24.                 const process_gif       *p) {
  25.   byte                  *rove;
  26.   int                   width, height;
  27.   int                   x, y;
  28.   const os_colour       *palette;
  29.   int                   line_length;
  30.   int                   *buffer, *this_row, *next_row;
  31.   int                   buffer_width;
  32.   int                   r, g, b;
  33.   int                   or, og, ob;
  34.   int                   t;
  35.   int                   er, eg, eb;
  36.  
  37.   assert(p);
  38.   assert(p->pixel_width > 0);
  39.   assert(p->pixel_height > 0);
  40.   assert(p->in_palette.colours);
  41.  
  42.   /*
  43.    * sierra2 requires storing error info for two pixels to right and two pixels to left
  44.    * so we will just allocate two extra columns for each row and not do any edge checks
  45.    * each entry is stored as {r*SCALE, g*SCALE, b*SCALE}
  46.    */
  47.   buffer_width = (2 + p->pixel_width + 2) * 3;
  48.   buffer = calloc(1, sizeof(*buffer) * (buffer_width * 2));
  49.   if (!buffer) {
  50.     /*
  51.      * oh dear
  52.      */
  53.     return TRUE;
  54.   }
  55.  
  56.   initialise_scaling_tables();
  57.  
  58.   /*
  59.    * not we pre-load values from the process_gif array
  60.    * because it considerably helps the compiler produce better code
  61.    */
  62.   rove = p->buffer;
  63.   width = p->pixel_width;
  64.   height = p->pixel_height;
  65.   palette = p->in_palette.colours;
  66.   line_length = p->line_length;
  67.   for (y= height; (y > 0); y--) {
  68.     if ((y & 7) == 0) {
  69.       xhourglass_percentage((y * 100) / height);
  70.     }
  71.     this_row = buffer + (buffer_width * ((y + 2) % 2)) + 2*3;
  72.     next_row = buffer + (buffer_width * ((y + 1) % 2)) + 2*3;
  73.     /* bottom row has no errors */
  74.     memset(next_row, 0, sizeof(*next_row) * (buffer_width - 2*3));
  75.     /*
  76.      * note that just because we are actually scanning/outputting right to left
  77.      * doesn't matter as far as the filter is concerned
  78.      * although it might help if we could ``snake''
  79.      */
  80.     for (x= width - 1; (x >= 0); x--) {
  81.       INPUT;
  82.       r += *this_row++;                                 /* add in errors from all rows */
  83.       g += *this_row++;
  84.       b += *this_row++;
  85.       PROCESS;
  86.       r -= or;  g -= og; b-= ob;                        /* error */
  87.       er = (r * 4) / 16; eg = (g * 4) / 16; eb = (b * 4) / 16;
  88.       this_row[ 0] += er; this_row[ 1] += eg; this_row[ 2] += eb;       /* this[ 1] += 4/16 */
  89.       or = r - er; g = og - eg; ob = b - eb;            /* remainder of error */
  90.  
  91.       er >>= 1; eg >>= 1; eb >>= 1;
  92.       next_row[ 3] += er; next_row[ 4] += eg; next_row[ 5] += eb;       /* next[ 1] += 2/16 */
  93.       next_row[-3] += er; next_row[-2] += eg; next_row[-1] += eb;       /* next[-1] += 2/16 */
  94.       or -= 2 * er; og -= 2 * eg; ob -= 2 * eb;
  95.  
  96.       er >>= 1; eg >>= 1; eb >>= 1;
  97.       next_row[-6] += er; next_row[-5] += eg; next_row[-4] += eb;       /* next[-2] += 1/16 */
  98.       or -= er; og -= eg; ob -= eb;
  99.  
  100.       er = (r * 3) / 16; eg = (g * 3) / 16; eb = (b * 3) / 16;
  101.       this_row[ 3] += er; this_row[ 4] += eg; this_row[ 5] += eb;       /* this[ 2] += 3/16 */
  102.       next_row[ 0] += er; next_row[ 1] += eg; next_row[ 2] += eb;       /* next[ 0] += 3/16 */
  103.       or -= 2 * er; og -= 2*eg; ob -= 2*eb;
  104.  
  105.       next_row[ 6] += or; next_row[ 7] += og; next_row[ 8] += ob;       /* next[ 2] += 1/16 */
  106.  
  107.       next_row += 3;                                    /* adjust next_row pointer */
  108.     }
  109.     rove += line_length;
  110.   }
  111.   free(buffer);
  112.   return FALSE;
  113. }
  114.